

// 常量
const MAX_COUNT: u32 = 100_0000;

fn main() {
    {
        // 变量默认不可变，可变需要加mut
        let mut x = 123;
        println!("变量：x = {}， 常量：{}", x, MAX_COUNT);
        x =21;
        println!("now x={}", x);

        // shadowing
        let x = "linxq";
        println!("变量隐藏：x={}", x);
        let x = x.len();
        println!("x = {}", x);
    }

    my_print(21);

    println!("2 + 3 = {}", add(2, 3));

    {
        // String
        let mut s = String::from("Hello,");
        s.push_str("Rust!");
        println!("{}", s);

        take_owership(s); // s 的所有权在函数里被移动，并在函数返回后被释放。
        // 从此开始 s 不再效

        let s1 = give_ownershipe(); // 返回值所有权转换给s1
        println!("{}", s1);
    }
    
    {
        // 借用 & 引用
        let str = String::from("你好");
        // &str 为指向str的引用，但不拥有它。
        let len = get_len(&str);
        println!("{} 长度 = {}", str, len);

        let mut str = String::from("你好");
        change_str(&mut str);
        println!("{}", str);
        // 下面三行不能编译：不能在拥有不可变引用的同时拥有可变引用
        // let r1 = &mut str;
        // let r2 = &str;
        // println!("{}, {}", r1, r2);
    }

    {
        // slice
        let mut s = String::from("Hello, Rust.");
        let word = first_word(&s); // 使用了&s不可变引用
        // s.clear(); // 当下面使用word时，这里编译错误，原因：引用不能同时存在可变（这里）和上一行的不可变引用。如果下面一行没有使用word，则可以。
        println!("第一个单词：{}", word);
    }

}

fn my_print(x: i32) {
    println!("参数：{}", x);
}

fn add(x:i32, y: i32) -> i32 {
    x + y
}

fn take_owership(str: String) {
    println!("{}", str);
}

fn give_ownershipe() -> String {
    let str = String::from("返回值的所有权被转移");
    str
}

// 将获取引用作为函数参数称为 借用（borrowing）
fn get_len(str: &String) -> usize { // str是引用，不拥有所有权。
    str.len()
}

fn change_str(str: &mut String) {
    str.push_str(", Rust！");
}

fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes(); // 转换为字节数组
    for (i, &e) in bytes.iter().enumerate() { // enumerate()返回元组：(元素索引, 对元素的引用)
        if e == b' ' {
            return &s[..i];
        }
    }

    &s[..]
}